const Koa = require('koa')
const KoaBody = require('koa-body')
const KoaLogger = require('koa-logger')
const jwt = require('jsonwebtoken')
const config = require('./config/config')
const router = require('./router')
const koaStatic = require('koa-static')
const securityUtil = require('./util/security')
const log4js = require('./config/log4js')

const log = log4js.getLogger()

const app = new Koa()

app.use(async (ctx, next) => {
  try {
    await next()
  } catch (error) {
    log.error(error)
    ctx.status = error.status || 500
    ctx.body = error
  }
})

app.use(async (ctx, next) => {
  const url = ctx.url
  if (url.startsWith('/api/auth')) {
    await next()
  } else if (!url.startsWith('/api/')) {
    await next()
  } else {
    try {
      const token = ctx.get('token') || ctx.request.query.token
      const dtoken = jwt.decode(token)
      if (!dtoken) {
        ctx.throw(403, 'invalid token')
      }
      const vtoken = jwt.verify(token, securityUtil.getSecret(dtoken.password))
      if (vtoken) {
        ctx.user = vtoken
        await next()
      } else {
        ctx.throw(403, 'invalid token')
      }
    } catch (error) {
      ctx.throw(403, 'invalid token')
    }
  }
})

app.use(KoaLogger({
  transporter: (str, args) => {
    log.trace(str)
  }
}))

app.use(koaStatic(config.getConf('server:static') || './static'))

app.use(KoaBody({
  patchNode: true,
  multipart: true
}))

app.use(async (ctx, next) => {
  if (ctx.request.querystring) {
    ctx.request.body = {
      ...ctx.request.body,
      ...ctx.request.query
    }
  }
  await next()
})

app.use(router.routes()).use(router.allowedMethods())

const port = config.getConf('server:port') || 3000
app.listen(port)

log.info(`application is running on http://localhost:${port}`)

require('./schedule/NetBooksDownloadJob')
